﻿/*
 *  Copyright 2009 Alessandro Pilotti
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace AlexPilotti.L2SQLDataModel.SchemaInfo
{
    [Flags]
    public enum ParameterDir { Input = 1, Output = 2, Return = 4, InputOutput = Input | Output }

    [Flags]
    public enum ProcedureType { ScalarFunction = 1, CLRScalarFunction = 2, CLRTableFunction = 4, InlineTableFunction = 8, Procedure = 16, CLRProcedure = 32, TableFunction = 64 }

    [Flags]
    public enum TableViewType {Table = 1, View = 2 }

    public class ColumnInfo
    {
        public string Name { get; set; }
        public Type DataType { get; set; }
        public int Length { get; set; }
        public int Precision { get; set; }
        public int Scale { get; set; }
        public bool AllowNull { get; set; }
        public bool IsAutoInc { get; set; }
        public bool IsComputed { get; set; }
        public string DBTypeComplete { get; set; }
        public string DBType { get; set; }
    }

    public class ConstraintInfo
    {
        public string Name { get; set; }
    }

    public class UniqueConstraintInfo : ConstraintInfo
    {
        public IList<String> ColumnNames { get; set; }
        public bool IsPrimaryKey { get; set; }

        public UniqueConstraintInfo()
        {
            ColumnNames = new List<string>();
        }
    }

    public class ForeignKeyConstraintInfo : ConstraintInfo
    {
        public IList<string> ColumnNames { get; set; }
        public TableInfo TargetTableInfo { get; set; }
        public UniqueConstraintInfo TargetConstraint { get; set; }

        public ForeignKeyConstraintInfo()
        {
            ColumnNames = new List<string>();
        }
    }

    public abstract class DBObjectInfo
    {
        public string Name { get; set; }
        public string SchemaName { get; set; }
    }

    public class TableInfo : DBObjectInfo
    {
        public IList<ColumnInfo> Columns { get; set; }
        public IList<ConstraintInfo> Constraints { get; set; }

        public TableInfo()
        {
            Columns = new List<ColumnInfo>();
            Constraints = new List<ConstraintInfo>();
        }
    }

    public class ParameterInfo
    {
        public string Name { get; set; }
        public ParameterDir ParameterDir { get; set; }
        public Type DataType { get; set; }
        public int Length { get; set; }
        public int Precision { get; set; }
        public int Scale { get; set; }
        public string DBTypeComplete { get; set; }
        public string DBType { get; set; }
    }    

    /// <summary>
    /// Stored procedures and functions
    /// </summary>
    public class ProcedureInfo : DBObjectInfo
    {
        public ProcedureType Type;
        public IList<TableInfo> ReturnTables { get; set; }
        public IList<ParameterInfo> Parameters { get; set; }

        public ProcedureInfo()
        {
            ReturnTables = new List<TableInfo>();
            Parameters = new List<ParameterInfo>();
        }
    }

    [Serializable]
    public class DBSchemaInfoErrorEventArgs : EventArgs
    {
        public Exception Exception { get; private set; }

        public DBSchemaInfoErrorEventArgs(Exception ex)
            : base()
        {
            Exception = ex;
        }
    }    


    public delegate void DBSchemaInfoErrorEventHandler(object sender, DBSchemaInfoErrorEventArgs e);

    public interface IDBSchemaInfo
    {
        event DBSchemaInfoErrorEventHandler HandleError;

        IList<TableInfo> GetTablesAndViewsInfo(IList<string> names, TableViewType type);
        IList<ProcedureInfo> GetProceduresInfo(IList<string> names);
    }
}
